<?php
/**
 * Created by PhpStorm.
 * User: Administrator
 * Date: 2016/11/22
 * Time: 14:04
 */
define('PATH_CONFIG', Chat_ROOT . '/conf');
define('PATH_CACHE', Chat_ROOT . '/cache');
define('PATH_CORE', Chat_ROOT . '/core');
define('PATH_LIB', PATH_CORE . '/library');
define('PATH_PUB', Chat_ROOT . '/public');
define('PATH_MOD', Chat_ROOT . '/model'); // -> /root/app/appA/model
define('PATH_CTL', Chat_ROOT . '/controller'); // -> /root/app/appA/controller

define('EXCEPT_CONFIG', -10001); // 加载配置异常
// 自加载
spl_autoload_register('autoload'); // aotuload注册

// 处理异常
set_exception_handler('exception_handler');
$defaultOutType = 'smarty';

/**
 * 自动加载魔术方法
 * 支持core系统下的Mod,Lib,Pub,Ctl及三种基础类的自动加载
 * @param 类名 $className
 * @return null
 */
function autoload($className)
{
    $_file = '';
    // controller model
    if ($className == 'Controller' || $className == 'Model' || $className == 'ExceptionHandler' || $className == 'BaseController') {
        $_file = PATH_CORE . '/' . $className . '.php';
    } else {
        // Mod,Lib,Pub,Ctl类的自动调用
        $clsPath = array('Mod' => PATH_MOD, 'Lib' => PATH_LIB, 'Pub' => PATH_PUB, 'Ctl' => PATH_CTL);
        $_classType = substr($className, 0, 3);
        if (isset($clsPath[$_classType])) {
            $_file = "{$clsPath[$_classType]}/" . basename($className) . '.php';
        }
    }
    if ($_file) {
        // auto中不能抛出错误
        if (!is_file($_file)) {
            exception_handler(new RuntimeException("File Not Found" . (DEBUG ? "({$className}:{$_file})" : ""), 405));
            exit;
        }
        require $_file;
        return true;
    }
    return false;
}

function load_config($config, $errStop = true)
{
    if (!$config && $errStop) {
        throw new LogicException('$config不能为空', EXCEPT_CONFIG);
    }
    $config = basename($config);
    // 判断 globals里是否已经有
    if (isset($GLOBALS['config'][$config])) {
        return $GLOBALS['config'][$config];
    }
    // 转为首字母大写
    $configPath = ucfirst($config);
    if (substr($configPath, 0, 4) == 'Conf') {
        $_file = PATH_CONFIG . '/' . $configPath . '.php';
    }else{
        $_file = "";
    }
    if (!is_file($_file) && $errStop) {
        throw new LogicException("config文件 {$config} 不存在", EXCEPT_CONFIG);
    }
    require $_file;
    return isset($GLOBALS['config'][$config]) ? $GLOBALS['config'][$config] : true;
}


/**
 * 路由实现,及默认模式
 * @param string $controller
 * @param string $action
 * @return boolean true/false
 */
function route($controller, $action, $defaultOut = 'smarty')
{
    global $defaultOutType;
    $defaultOutType = $defaultOut;
    $ctlClass = "Ctl" . ucfirst($controller);

    $_conObj = new $ctlClass;
    // 指定默认的输出格式
    $_conObj->setOutType($defaultOut);

    if ($defaultOut == 'smarty' && empty($_conObj->tpl)) {
        if ($action == 'index') {
            $_conObj->tpl = "{$controller}.tpl";
        } else {
            $_conObj->tpl = "{$controller}_{$action}.tpl";
        }
    }
    // 禁止访问Controller下的方法
    $reflection = new ReflectionClass('Controller');
    if ($reflection->hasMethod($action)) {
        throw new RuntimeException('Forbidden' . (DEBUG ? ":{$controller}/{$action}" : ''), 403);
    }

    // 方法不存在
    if (!method_exists($_conObj, $action) && !method_exists($_conObj, '__call')) {
        throw new RuntimeException('Not Found' . (DEBUG ? ":{$controller}/{$action}" : ''), 404);
    }

    $_conObj->$action();
    $_conObj->display();
    return true;
}

/**
 * 默认处理exception的方法
 * @param Exception $e
 */
function exception_handler(Exception $e)
{
    global $defaultOutType;
    $exceptionHandler = new ExceptionHandler($defaultOutType);
    $exceptionHandler->handler($e);
}